<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>FreeBASIC GTK</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="FreeBASIC, tutorial, GTK">
<meta name="description" content="This is FreeBASIC GTK tutorial. In this tutorial, we will
learn the basics of GUI programming with FreeBASIC &amp; GTK.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">


<a href="/" title="Home">Home</a>



<h1>FreeBASIC GTK tutorial</h1>


<p>
This is FreeBASIC GTK tutorial. In this tutorial, we will create graphical user
interface in the GTK library with the FreeBASIC language. The tutorial is suitable 
for beginners. Once you know the basics and you know how to use the GTK and the
FreeBASIC together, you can just continue learning the GTK library from 
the <a href="/tutorials/gtktutorial/">GTK+ tutorial</a>.
</p>

<div class="center">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* top_horizontal */
google_ad_slot = "3327173442";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<p>
FreeBASIC is different from other languages that work with GTK. There is no such a 
binding like PyGTK or GTK#. In FreeBASIC, we directly call the C code in the program.
This way, FreeBASIC is closely tied to the C language.
</p>


<h2>FreeBASIC</h2>


<p>
FreeBASIC is a popular BASIC (Beginner's All-purpose Symbolic Instruction Code) compiler. It
appeared in 2004 and was influenced by QuickBASIC and C languages. FreeBASIC is
a free, open-source, 32-bit BASIC compiler. To fully support many C libraries, many
features have been added like pointers, preprocessor, macros, which cannot be found
in other BASIC compilers. 
</p>

<h2>GTK</h2>

<p>
The GTK is a library for creating graphical user interfaces. The library is created in 
C programming language. The GTK library is also called the GIMP Toolkit. Originally, the 
library was created while developing the GIMP image manipulation program. Since then, 
the GTK became one of the most popular toolkits under Linux and BSD Unix. Today, most of 
the GUI software in the open source world is created in Qt or in GTK.
Language bindings exist for C++, Python, Perl, Java, C# and other programming languages.
</p>

<h2>First example</h2>

<p>
In our first code example, we will center a small 
window on the screen. 
</p>


<pre class="code">
' ZetCode FreeBASIC GTK tutorial
'
' This program centers a window on 
' the screen
'
' author Jan Bodnar
' last modified July 2010
' website www.zetcode.com

#include once "gtk/gtk.bi"

#define NULL 0

Dim As GtkWidget Ptr win

gtk_init(NULL, NULL)

win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_title(GTK_WINDOW(win), "Center")
gtk_widget_set_size_request(win, 250, 150)
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER)

g_signal_connect(G_OBJECT(win), "destroy", _
    G_CALLBACK (@gtk_main_quit), NULL)

gtk_widget_show(win)
gtk_main()

END 0
</pre>

<p>
This code centers a window on the screen. It is a mix of
FreeBASIC and C code.
</p>

<pre class="explanation">
#include once "gtk/gtk.bi"
</pre>

<p>
This is a header file needed to run GTK code from FreeBASIC.
</p>

<pre class="explanation">
#define NULL 0
</pre>

<p>
There is no built-in NULL value in FreeBASIC. To more closely resemble the 
GTK C code, we define a NULL value. 
</p>

<pre class="explanation">
Dim As GtkWidget Ptr win
</pre>

<p>
We declare a pointer to the <b>GtkWidget</b>.
</p>

<pre class="explanation">
gtk_init(NULL, NULL)
</pre>

<p>
We initiate the GTK library.
</p>

<pre class="explanation">
win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
</pre>

<p>
We create a window which is a <b>GtkWidget</b>. 
The window type is <b>GTK_WINDOW_TOPLEVEL</b>. 
Toplevel windows have a titlebar and a border. They are managed by the window manager.
</p>


<pre class="explanation">
gtk_window_set_title(GTK_WINDOW(win), "Center")
gtk_widget_set_size_request(win, 250, 150)
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER)
</pre>

<p>
These three lines set a title for the window, resize the window and
position it to the center of the screen. 
</p>

<pre class="explanation">
g_signal_connect(G_OBJECT(win), "destroy", _
    G_CALLBACK (@gtk_main_quit), NULL)
</pre>

<p>
If we click on the x mark, or press Alt + F4 to terminate the application, a destroy
signal is emitted. The window does not react to the destroy signal by default. 
We must explicitly terminate the application by connecting the destroy signal 
to the <b>gtk_main_quit()</b> function. 
There are two important characters. The underscore and
the @ character. The underscore is a line continuation character in FreeBASIC. We must
use it, if a code line exceeds more that one line. The at (@) character gives us the 
address of the <b>gtk_main_quit()</b> function. In C, a function name is 
an address to the function. This is not true in FreeBASIC, that is why we use the @ character.
</p>

<pre class="explanation">
gtk_widget_show(win)
</pre>

<p>
The window has been created in memory. Now we use the <b>gtk_widget_show</b>
function to show the window on the screen. 
</p>

<pre class="explanation">
gtk_main()
</pre>

<p>
We enter the mainloop of the application.
From this point, the application sits and waits for events to happen.
</p>

<pre class="explanation">
END 0
</pre>

<p>
We finish FreeBASIC code.
</p>

<pre class="code">
$ fbc simple.bas
$ ./simple
</pre>

<p>
We compile and run the example.
</p>


<img src="/img/gui/freebasicgtk/simple.png" alt="Simple example">
<div class="figure">Figure: Simple example</div>



<h2>Close button</h2>

<p>
In the second example, we place a button widget on 
the window. First, we place a fixed container on the
window and onto this container, we position our button.
Clicking on the button will terminate the application.
</p>

<pre class="code">
' ZetCode FreeBASIC GTK tutorial
'
' In this example, we place a close
' button on the window. Clicking on the
' button will terminate the application.
'
' author Jan Bodnar
' last modified July 2010
' website www.zetcode.com

#include once "gtk/gtk.bi"

#define NULL 0

Dim As GtkWidget Ptr win
Dim As GtkWidget Ptr fixed
Dim As GtkWidget Ptr button

gtk_init(NULL, NULL)

win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_title(GTK_WINDOW(win), "Close")
gtk_widget_set_size_request(win, 250, 150)
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER)

g_signal_connect(G_OBJECT(win), "destroy", _
    G_CALLBACK (@gtk_main_quit), NULL)

fixed = gtk_fixed_new()
gtk_container_add(GTK_CONTAINER(win), fixed)
       
button = gtk_button_new_with_label("Close")
gtk_widget_set_size_request(button, 80, 35)

gtk_fixed_put(GTK_FIXED(fixed), button, 50, 50)

g_signal_connect(G_OBJECT(button), "clicked", _
    G_CALLBACK (@gtk_main_quit), NULL)
      
gtk_widget_show_all(win)

gtk_main()

END 0
</pre>

<p>
This is source code for the close button example.
</p>

<pre class="explanation">
Dim As GtkWidget Ptr win
Dim As GtkWidget Ptr fixed
Dim As GtkWidget Ptr button
</pre>

<p>
We declare three variables. One for the toplevel window, which
is the base skeleton of a GUI application. One for the container.
The container is a special kind of widget. It is not visible. Its
sole purpose is to contain other widget. In our case, the button
widget. 
</p>

<pre class="explanation">
fixed = gtk_fixed_new()
gtk_container_add(GTK_CONTAINER(win), fixed)
</pre>

<p>
These two lines create a container widget and place it
inside the window widget. 
</p>

<pre class="explanation">
button = gtk_button_new_with_label("Close")
gtk_widget_set_size_request(button, 80, 35)
</pre>

<p>
We create a button widget and make it 80x35 px.
</p>

<pre class="explanation">
gtk_fixed_put(GTK_FIXED(fixed), button, 50, 50)
</pre>

<p>
We put a button into the container at x=50, y=50 coordinates.
This is called absolute positioning. It is suitable for small
examples, but in more complicated programs, we use
layout managers.
</p>

<pre class="explanation">
g_signal_connect(G_OBJECT(button), "clicked", _
    G_CALLBACK (@gtk_main_quit), NULL)
</pre>

<p>
When we click on the button, a clicked signal is emitted. 
The <b>g_signal_connect()</b> function connects
a callback, in our case the built-in <b>gtk_main_quit()</b> 
function, to the <b>clicked</b> signal emitted by the
button widget.
</p>

<pre class="explanation">
gtk_widget_show_all(win)
</pre>

<p>
We have created three widgets. We could call <b>gtk_widget_show()</b>
on each of them, or we call <b>gtk_widget_show_all()</b> on the window widget,
which shows all three widgets in one step. 
</p>

<img src="/img/gui/freebasicgtk/closebutton.png" alt="Close button">
<div class="figure">Figure: Close button</div>



<h2>Displaying an image</h2>

<p>
In the following example, we display an image on the window.
</p>

<pre class="code">
' ZetCode FreeBASIC GTK tutorial
'
' This example shows an image on 
' the window
'
' author Jan Bodnar
' last modified July 2010
' website www.zetcode.com

#include once "gtk/gtk.bi"
#include once "gtk/gdk.bi"

#define NULL 0

Dim As GtkWidget Ptr win
Dim As GtkWidget Ptr image

gtk_init(NULL, NULL)

win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_title(GTK_WINDOW(win), "Red Rock")
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER)

g_signal_connect(G_OBJECT(win), "destroy", _
    G_CALLBACK (@gtk_main_quit), NULL)

gtk_window_set_resizable(GTK_WINDOW(win), FALSE)
gtk_container_set_border_width(GTK_CONTAINER(win), 2)

image = gtk_image_new_from_file("redrock.png")
gtk_container_add(GTK_CONTAINER(win), image)
      
gtk_widget_show_all(win)

gtk_main()

END 0
</pre>

<p>
We show an image on the window. 
</p>

<pre class="explanation">
Dim As GtkWidget Ptr win
Dim As GtkWidget Ptr image
</pre>

<p>
We only have two widgets in this example. A window widget and 
an image widget. 
</p>

<pre class="explanation">
gtk_window_set_resizable(GTK_WINDOW(win), FALSE)
</pre>

<p>
The window cannot be resized. Note, that we did not set a size
for the window. In such a case, the window will automatically 
fit the size of the image. 
</p>

<pre class="explanation">
gtk_container_set_border_width(GTK_CONTAINER(win), 2)
</pre>

<p>
We put some empty space around the container. 
</p>

<pre class="explanation">
image = gtk_image_new_from_file("redrock.png")
gtk_container_add(GTK_CONTAINER(win), image)
</pre>

<p>
We create an image widget from a png file. We place the image
to the window. The window is itself a simple container. It can 
contain exactly one widget. 
</p>


<h2>Simple menu example</h2>

<p>
In the next code example, we will create a simple menu.
</p>

<pre class="code">
' ZetCode FreeBASIC GTK tutorial
'
' This example shows a simple menu
'
' author Jan Bodnar
' last modified July 2010
' website www.zetcode.com

#include once "gtk/gtk.bi"

#define NULL 0

Dim As GtkWidget Ptr win
Dim As GtkWidget Ptr vbox

Dim As GtkWidget Ptr menubar
Dim As GtkWidget Ptr fmenu
Dim As GtkWidget Ptr fmi
Dim As GtkWidget Ptr qmi


gtk_init(NULL, NULL)

win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_title(GTK_WINDOW(win), "Simple menu")
gtk_widget_set_size_request(win, 250, 150)
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER)

g_signal_connect(G_OBJECT(win), "destroy", _
    G_CALLBACK (@gtk_main_quit), NULL)

vbox = gtk_vbox_new(FALSE, 0)
gtk_container_add(GTK_CONTAINER(win), vbox)


menubar = gtk_menu_bar_new()
fmenu = gtk_menu_new()

fmi = gtk_menu_item_new_with_label("File")
qmi = gtk_menu_item_new_with_label("Quit")

gtk_menu_item_set_submenu(GTK_MENU_ITEM(fmi), fmenu)
gtk_menu_shell_append(GTK_MENU_SHELL(fmenu), qmi)
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fmi)
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0)

g_signal_connect(G_OBJECT(qmi), "activate", _
    G_CALLBACK(@gtk_main_quit), NULL)
      
gtk_widget_show_all(win)

gtk_main()

END 0
</pre>

<p>
These code lines create a simple menu. It has only one menu item, which 
when selected will terminate the application. Creating a menubar is a bit confusing.
We must bear in mind that both a menubar and menus are derived from the same widget, 
namely a menu shell. menu items are only valid childs for menus. 
They are also used to implement submenus.
</p>

<pre class="explanation">
Dim As GtkWidget Ptr win
Dim As GtkWidget Ptr vbox

Dim As GtkWidget Ptr menubar
Dim As GtkWidget Ptr fmenu
Dim As GtkWidget Ptr fmi
Dim As GtkWidget Ptr qmi
</pre>

<p>
We have six variables for six widgets. One widget is a vertical box, which will 
set up the layout. A menubar is a horizontal widget, on which we place menus. The menus
contain menu items, which do some actions. Like saving a document or terminating the application. 
</p>

<pre class="explanation">
vbox = gtk_vbox_new(FALSE, 0)
gtk_container_add(GTK_CONTAINER(win), vbox)
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 3)
</pre>

<p>
We create a vertical box and make it to be the container for the
toplevel window. The first parameter of the <b>gtk_vbox_new()</b>
function is called the homogenous parameter. If set to TRUE, all 
widgets in a box has equal space allottings. We do not want this, because
a menubar takes only a smaller portion of the window. The second parameter is space
between children. 
</p>


<pre class="explanation">
menubar = gtk_menu_bar_new()
fmenu = gtk_menu_new()
</pre>

<p>
In this code we create a menubar and a menu.
</p>

<pre class="explanation">
fmi = gtk_menu_item_new_with_label("File")
qmi = gtk_menu_item_new_with_label("Quit")
</pre>

<p>
Two menu items are created. 
</p>

<pre class="explanation">
gtk_menu_item_set_submenu(GTK_MENU_ITEM(fmi), fmenu)
</pre>

<p>
This code line implements a file menu. The logic is that the menubar
is a menu shell. The file menu is also a menu shell. 
That's why we look at the file menu as a submenu or a subshell.
</p>

<pre class="explanation">
gtk_menu_shell_append(GTK_MENU_SHELL(fmenu), qmi)
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fmi)
</pre>

<p>
Menu items are implemented by calling the <b>gtk_menu_shell_append()</b> function. 
The menu items are appended to menu shells. In our case, the quit menu item is 
appended to a file menu and also the file menu item is appended to the menubar.
</p>

<pre class="explanation">
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0)
</pre>

<p>
The <b>gtk_box_pack_start()</b> function call adds the menubar to the
vertical box. The first parameter is the container, where we put the child widget. The
second parameter is the child widget. The third parameter is <b>expand</b> parameter. Children
with expand parameter set to TRUE will take up additional space from the vertical box.
This additional space would be evenly distributed among them. We don't want the menubar to 
take up any additional space, so we set the expand parameter to FALSE. The fourth parameter
has no effect, if the expand is set to FALSE. The last parameter is padding, which adds some extra
space among child widgets. We don't add any extra space. 
</p>

<pre class="explanation">
g_signal_connect(G_OBJECT(qmi), "activate", _
    G_CALLBACK(@gtk_main_quit), NULL)
</pre>

<p>
By selecting the quit menu item, we terminate the application.
</p>


<img src="/img/gui/freebasicgtk/simplemenu.png" alt="Simple menu">
<div class="figure">Figure: Simple menu example</div>



<h2>The enter signal</h2>

<p>
The following example will show, how we can react to an enter signal. 
The enter signal is emitted, when we enter the area of a widget with a mouse pointer.
</p>

<pre class="code">
' ZetCode FreeBASIC GTK tutorial
'
' In this code example, we react to the
' enter signal by changing the background
' color of a button widget
'
' author Jan Bodnar
' last modified July 2010
' website www.zetcode.com

#include once "gtk/gtk.bi"

#define NULL 0

Dim As GtkWidget Ptr win
Dim As GtkWidget Ptr fixed
Dim As GtkWidget Ptr btn


Sub enter_button Cdecl (Byval widget As GtkWidget Ptr, _
    Byval dat As gpointer)
 
  Dim col As GdkColor

  col.red = 27000
  col.green = 30325
  col.blue = 34181
  gtk_widget_modify_bg(widget, GTK_STATE_PRELIGHT, @col)
  
End Sub


gtk_init(NULL, NULL)

win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_title(GTK_WINDOW(win), "enter signal")
gtk_widget_set_size_request(win, 230, 150)
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER)

g_signal_connect(G_OBJECT(win), "destroy", _
    G_CALLBACK (@gtk_main_quit), NULL)

fixed = gtk_fixed_new()
gtk_container_add(GTK_CONTAINER(win), fixed)

btn = gtk_button_new_with_label("Button")
gtk_widget_set_size_request(btn, 80, 35)
gtk_fixed_put(GTK_FIXED(fixed), btn, 50, 50)

g_signal_connect(G_OBJECT(btn), "enter", _
    G_CALLBACK(@enter_button), NULL)
      
gtk_widget_show_all(win)

gtk_main()

END 0
</pre>

<p>
We put a button widget into a fixed container. The 
<b>enter_button()</b> subroutine is called, 
when we enter the area of the button widget. Inside the subroutine, 
we change the background color of the button. 
</p>

<pre class="explanation">
Sub enter_button Cdecl (Byval widget As GtkWidget Ptr, _
    Byval dat As gpointer)
...
End Sub
</pre>

<p>
This is the <b>enter_button()</b> subroutine, in which we
react to the <b>enter</b> signal. The <b>Cdecl</b>
keyword specifies the calling convention of the subroutine. In this calling convention,
any parameters are passed in the reverse order in which they are listed,
that is, from right to left. In our case, it does not matter though.
</p>

<pre class="explanation">
Dim col As GdkColor
</pre>

<p>
We create a local <b>GdkColor</b> variable. It is a structure
used to describe a color in GTK applications. 
</p>

<pre class="explanation">
col.red = 27000
col.green = 30325
col.blue = 34181
</pre>

<p>
Here we set the color. 
</p>

<pre class="explanation">
gtk_widget_modify_bg(widget, GTK_STATE_PRELIGHT, @col)
</pre>

<p>
The <b>gtk_widget_modify_bg()</b> sets the background color for 
a widget in a particular state. In our case the state is the <b>GTK_STATE_PRELIGHT</b>, 
which is when the mouse pointer is over the widget. The third parameter is a pointer
to the color structure. 
</p>

<pre class="explanation">
g_signal_connect(G_OBJECT(btn), "enter", _
    G_CALLBACK(@enter_button), NULL)
</pre>

<p>
Here we connect the <b>enter_button()</b> subroutine to the
<b>enter</b> signal emitted by the button widget. 
</p>


<h2>Check button example</h2>

<p>
In the following example, we put a check button into the 
fixed container. We will show and hide the title of the window
by checking and unchecking of the check button. 
</p>

<pre class="code">
' ZetCode FreeBASIC GTK tutorial
'
' This example a check button widget
' toggles the title of the window
'
' author Jan Bodnar
' last modified July 2010
' website www.zetcode.com

#include once "gtk/gtk.bi"

#define NULL 0

Dim As GtkWidget Ptr win
Dim As GtkWidget Ptr cbtn
Dim As GtkWidget Ptr frame

Sub toggle_title Cdecl (Byval widget As GtkWidget Ptr, _
    Byval win As gpointer)

  If gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) Then
      gtk_window_set_title(win, "Check button")
  Else 
      gtk_window_set_title(win, "")
  End If
End Sub


gtk_init(NULL, NULL)

win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_title(GTK_WINDOW(win), "Check button")
gtk_widget_set_size_request(win, 250, 150)
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER)

g_signal_connect(G_OBJECT(win), "destroy", _
    G_CALLBACK (@gtk_main_quit), NULL)

frame = gtk_fixed_new()
gtk_container_add(GTK_CONTAINER(win), frame)

cbtn = gtk_check_button_new_with_label("Show title")
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cbtn), TRUE)
gtk_fixed_put(GTK_FIXED(frame), cbtn, 50, 50)

g_signal_connect(cbtn, "clicked", _
    G_CALLBACK(@toggle_title), cast(gpointer, win))
      
gtk_widget_show_all(win)

gtk_main()

END 0
</pre>

<p>
This is the code to the check button example. 
</p>

<pre class="explanation">
Sub toggle_title Cdecl (Byval widget As GtkWidget Ptr, _
    Byval win As gpointer)
</pre>

<p>
We call the <b>toggle_title()</b> function, if we
click on the check button. In this case, we need pointers to two objects.
We need a pointer to the check button to determine if it is checked or not.
And we also need the pointer to the window to set or unset its title.
</p>

<pre class="explanation">
If gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) Then
    gtk_window_set_title(win, "Check button")
Else 
    gtk_window_set_title(win, "")
</pre>

<p>
We determine the state of the check button with the 
<b>gtk_toggle_button_get_active()</b> function.
We set the title of the window with the <b>gtk_window_set_title()</b>
function.
</p>

<pre class="explanation">
g_signal_connect(cbtn, "clicked", _
    G_CALLBACK(@toggle_title), cast(gpointer, win))
</pre>

<p>
The last parameter of the <b>g_signal_connect()</b> is usually
some data, that we want to pass to the callback function. This time, we needed
to pass another pointer to a window object. In such a case, we need to do
casting. This is because the function expects a <b>gpointer</b>
and the window is of <b>GtkWidget</b> type. FreeBASIC has
a <b>case</b> keyword to do the casting.
</p>


<img src="/img/gui/freebasicgtk/checkbutton.png" alt="Check button">
<div class="figure">Figure: Check button example</div>



<h2>Combo box example</h2>

<p>
In the last example of the FreeBASIC GTK tutorial, we
will present the combo box widget. 
</p>

<pre class="code">
' ZetCode FreeBASIC GTK tutorial
'
' In this example, we present the combo box
' widget
'
' author Jan Bodnar
' last modified July 2010
' website www.zetcode.com

#include once "gtk/gtk.bi"

#define NULL 0

Dim As GtkWidget Ptr win
Dim As GtkWidget Ptr combo
Dim As GtkWidget Ptr fixed
Dim As GtkWidget Ptr label


Sub combo_selected Cdecl (Byval widget As GtkWidget Ptr, _
    Byval win As gpointer)
 
  Dim As gchar Ptr text

  text =  gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget))
  gtk_label_set_text(GTK_LABEL(win), text)
  g_free(text)
End Sub


gtk_init(NULL, NULL)

win = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_title(GTK_WINDOW(win), "Check button")
gtk_widget_set_size_request(win, 230, 150)
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER)

g_signal_connect(G_OBJECT(win), "destroy", _
    G_CALLBACK (@gtk_main_quit), NULL)

fixed = gtk_fixed_new()

combo = gtk_combo_box_new_text()
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Ubuntu")
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Mandriva")
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Fedora")
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Mint")
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Gentoo")
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Debian")

gtk_fixed_put(GTK_FIXED(fixed), combo, 50, 50)
gtk_container_add(GTK_CONTAINER(win), fixed)

label = gtk_label_new("-")
gtk_fixed_put(GTK_FIXED(fixed), label, 50, 110)

g_signal_connect(G_OBJECT(combo), "changed", _
    G_CALLBACK(@combo_selected), cast(gpointer, label))
      
gtk_widget_show_all(win)

gtk_main()

END 0
</pre>

<p>
We have two widgets: combo box and a label. An option selected from the
combo box will be shown in the label. 
</p>

<pre class="explanation">
Dim As gchar Ptr text

text =  gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget))
gtk_label_set_text(GTK_LABEL(win), text)
g_free(text)
</pre>

<p>
In these lines, we retrieve the text from the combo box and
set it to the label. We work with a pointer to the <b>gchar</b>. It
is a basic type of the <b>glib</b> library, which is a foundation for the 
GTK library. We release the memory that was created while retrieving text
from the combo box.
</p>

<pre class="explanation">
combo = gtk_combo_box_new_text()
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Ubuntu")
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Mandriva")
...
</pre>

<p>
Combo box widget is created and filled with data. 
</p>

<pre class="explanation">
label = gtk_label_new("-")
gtk_fixed_put(GTK_FIXED(fixed), label, 50, 110)
</pre>

<p>
Label widget is created and put insid the container. 
</p>

<pre class="explanation">
g_signal_connect(G_OBJECT(combo), "changed", _
    G_CALLBACK(@combo_selected), cast(gpointer, label))
</pre>

<p>
We plug a <b>combo_selected()</b> function
to the <b>changed</b> signal of the combo box.
We again do the casting. 
</p>


<img src="/img/gui/freebasicgtk/combobox.png" alt="A combo box widget">
<div class="figure">Figure: A combo box widget</div>

<p>
This was the FreeBASIC GTK tutorial. We had several examples, which showed how we can
work with the FreeBASIC language and the GTK library. These examples clearly showed that
we mix FreeBASIC and C languages. Once you know how to bled these together,
you just do the GTK programming. More about the GTK library can be 
found <a href="/tutorials/gtktutorial/">here</a>.
</p>



<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified July 11, 2010  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>
